import pandas as pd
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
from sklearn.preprocessing import StandardScaler

from RF import preprocess_data
from SVM import split_data, plot_confusion_matrix, predict_and_evaluate, plot_roc_curve, plot_metrics
from util.LoadData import load_data

# file_path = r'D:\dongtu\software-defect-prediction\dataset\KC1.arff'
# df= load_data(file_path)
# df_imputed = preprocess_data(df)
# # 4. 划分数据集
# X_train, X_test, y_train, y_test = split_data(df_imputed)
# # 初始化逻辑回归模型
# model = LogisticRegression(solver='lbfgs', max_iter=1000)  # 你可以设置一些初始参数，但调优时会覆盖它们
#
# # 定义要搜索的参数网格
# param_grid = {
#     'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000],  # 正则化强度的倒数
#     'penalty': ['l1', 'l2'],  # 正则化类型
#     'class_weight': ['balanced', None],  # 类别权重的平衡选项
#     # 注意：'solver'参数在这里没有包含在内，因为'lbfgs'是逻辑回归的默认solver，且对于大多数参数来说，它都工作得很好
#     # 如果你需要尝试不同的solver，可以在这里添加它，但请注意，不是所有的参数组合都适用于所有的solver
# }
#
# # 初始化GridSearchCV对象
# grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=5, scoring='accuracy', verbose=2, n_jobs=-1)
#
# # 执行参数搜索
# grid_search.fit(X_train, y_train)
#
# # 输出最佳参数和对应的评分
# print("最佳参数：", grid_search.best_params_)
# print("最佳评分（准确率）：", grid_search.best_score_)
# # 使用最佳参数训练模型
# best_model = grid_search.best_estimator_
# # 如果需要，你可以使用best_model进行预测
#
# # 示例：使用最佳模型进行预测并评估（这里只是示例，因为我们已经有了真实的y）
# y_pred = best_model.predict(X_test)
# print("预测的准确率：", accuracy_score(y_test, y_pred))
#
# # 使用最佳参数训练模型
# best_model = grid_search.best_estimator_
#
# # 6. 模型评估
# y_pred = best_model.predict(X_test)
# accuracy = accuracy_score(y_test, y_pred)
# print(f'Accuracy: {accuracy:.2f}')
#
# # 混淆矩阵
# print("Confusion Matrix:")
# print(confusion_matrix(y_test, y_pred))
# plot_confusion_matrix(confusion_matrix(y_test, y_pred), 'picture/Logic/Confusion_Matrix.png')
#
# # 分类报告
# print("Classification Report:")
# print(classification_report(y_test, y_pred))



def train_model(file_path):
    df = load_data(file_path)
    df_imputed = preprocess_data(df)
    # 4. 划分数据集
    X_train, X_test, y_train, y_test = split_data(df_imputed)
    # 初始化逻辑回归模型
    model = LogisticRegression(solver='lbfgs', max_iter=1000)  # 你可以设置一些初始参数，但调优时会覆盖它们
    # 定义要搜索的参数网格
    param_grid = {
        'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000],  # 正则化强度的倒数
        'penalty': ['l1', 'l2'],  # 正则化类型
        'class_weight': ['balanced', None],  # 类别权重的平衡选项
        # 注意：'solver'参数在这里没有包含在内，因为'lbfgs'是逻辑回归的默认solver，且对于大多数参数来说，它都工作得很好
        # 如果你需要尝试不同的solver，可以在这里添加它，但请注意，不是所有的参数组合都适用于所有的solver
    }

    # 初始化GridSearchCV对象
    grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=5, scoring='accuracy', verbose=2, n_jobs=-1)
    # 执行参数搜索
    grid_search.fit(X_train, y_train)
    # 输出最佳参数和对应的评分
    print("最佳参数：", grid_search.best_params_)
    print("最佳评分（准确率）：", grid_search.best_score_)
    # 使用最佳参数训练模型
    best_model = grid_search.best_estimator_
    # 如果需要，你可以使用best_model进行预测
    # 使用最佳参数训练模型
    best_model = grid_search.best_estimator_
    return best_model,X_test,y_test


def predict_model(model,X_test,y_test):
    y_pred,y_pred_prob,report,conf_matrix=predict_and_evaluate(model,X_test,y_test)
    return y_pred,y_pred_prob,report,conf_matrix


def show_prediction_results(y_test,y_pred_prob,report,conf_matrix):
    # 绘制评估指标
    metrics_0 = {
        'Accuracy': report['accuracy'],
        'Precision_0': report['0']['precision'],
        'Recall_0': report['0']['recall'],
        'F1_Score_0': report['0']['f1-score']
    }
    plot_metrics(metrics_0, 'Classification Metrics for Class 0 (Defect)', 'picture/Logic/classification_metrics_0.png')

    metrics_1 = {
        'Accuracy': report['accuracy'],
        'Precision_1': report['1']['precision'],
        'Recall_1': report['1']['recall'],
        'F1_Score_1': report['1']['f1-score']
    }
    plot_metrics(metrics_1, 'Classification Metrics for Class 1 (NO Defect)',
                 'picture/Logic/classification_metrics_1.png')
    # 绘制 ROC 曲线
    plot_roc_curve(y_test, y_pred_prob, 'picture/Logic/roc_curve_and_auc.png')
    # 绘制混淆矩阵
    plot_confusion_matrix(conf_matrix, 'picture/Logic/Confusion_Matrix.png')

def main():
    file_path = r'D:\dongtu\software-defect-prediction\dataset\KC1.arff'
    best_model, X_test, y_test= train_model(file_path)
    y_pred,y_pred_prob,report,conf_matrix=predict_model(best_model, X_test, y_test)
    show_prediction_results(y_test,y_pred_prob,report,conf_matrix)
#程序入口点
if __name__ == '__main__':
    main()